package com.example.mybluetooth.adapter;

import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;

import com.example.mybluetooth.BluetoothUtils;
import com.example.mybluetooth.R;
import com.example.mybluetooth.ToastUtils;
import com.example.mybluetooth.bean.ADStructure;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import static android.bluetooth.BluetoothGattService.SERVICE_TYPE_PRIMARY;
import static android.bluetooth.BluetoothGattService.SERVICE_TYPE_SECONDARY;
import static com.example.mybluetooth.BluetoothUtils.hexStringToBytes;

public class BleConnectionAdapter extends RecyclerView.Adapter{
    @NonNull
    private  Context context;
    @NonNull
    private BleConnectionHelper bleConnectionHelper;


    public BleConnectionAdapter(Context context, BleConnectionHelper bleConnectionHelper) {
        this.context = context;
        this.bleConnectionHelper = bleConnectionHelper;
    }

    @NonNull
    @Override
    public BleConnectionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View inflate = LayoutInflater.from(this.context).inflate(R.layout.bleclient_list_item, parent, false);
        return  new BleConnectionViewHolder(inflate);
    }

    @Override
    public int getItemCount() {
        return BleConnectionHelper.getMGattServiceList().size();
    }

    @NonNull
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    //参数类型不能修改，否则，不能覆盖父类的方法，需要在函数体中转换类型后再使用子类的方法
        BluetoothGattService data = BleConnectionHelper.getMGattServiceList().get(position);
        BleConnectionViewHolder viewHolder= (BleConnectionViewHolder)holder;
        viewHolder.bindData(data);
    }




    class BleConnectionViewHolder extends RecyclerView.ViewHolder {
        private Context mContext;
        //GattService的名称
        private TextView serviceName;
        //GattService的UUID
        private TextView uuidTextView;
        //GattService的类型
        private TextView serviceType;
        //service布局
        private ConstraintLayout serviceLayout;
        //characteristic布局
        private LinearLayout characteristicLayout;
        //二级服务布局
        private LinearLayout secondaryServiceLayout;
        //隐藏布局
        private FrameLayout otherLayout;

        //存储广播数据单元数组
        private ArrayList<ADStructure> mADStructureArray = new ArrayList<>();

        // 在构造函数中执行初始化
        public BleConnectionViewHolder(@NonNull View itemView) {
            super(itemView);
            mContext = itemView.getContext();
            serviceName = itemView.findViewById(R.id.textView);
            uuidTextView = itemView.findViewById(R.id.uuidTextView);
            serviceType = itemView.findViewById(R.id.serviceType);
            serviceLayout = itemView.findViewById(R.id.serviceLayout);
            characteristicLayout = itemView.findViewById(R.id.characteristicLayout);
            secondaryServiceLayout = itemView.findViewById(R.id.secondaryServiceLayout);
            otherLayout = itemView.findViewById(R.id.otherLayout);
            serviceLayout.setOnClickListener(v -> {
                if (otherLayout.getVisibility() == View.GONE) {
                    otherLayout.setVisibility(View.VISIBLE);
                } else {
                    otherLayout.setVisibility(View.GONE);
                }
            });
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        public void bindData(BluetoothGattService service) {
            //设置服务的UUID
            uuidTextView.setText(service.getUuid().toString());

            //设置服务的类型
            switch (service.getType()) {
                case SERVICE_TYPE_PRIMARY: {
                    serviceType.setText("PRIMARY SERVICE");
                    break;
                }
                case SERVICE_TYPE_SECONDARY: {
                    serviceType.setText("SECONDARY SERVICE");
                    break;
                }
            }
            //移除原本全部的特征
            characteristicLayout.removeAllViews();
            switch (service.getUuid().toString()) {
                case "00001801-0000-1000-8000-00805f9b34fb": {
                    serviceName.setText("Generic Attribute");
                    break;
                }
                case "00001800-0000-1000-8000-00805f9b34fb": {
                    serviceName.setText("Generic Access");
                    break;
                }
                default: {
                    serviceName.setText("Service");
                    //遍历特征
                    if (service.getCharacteristics() != null) {
                        for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                            addCharacteristicLayout(characteristic);
                        }
                    }
                }
            }
        }

        /**
         * 添加特征值布局
         */
        public void addCharacteristicLayout(BluetoothGattCharacteristic characteristic) {
            View view = LayoutInflater.from(mContext).inflate(
                    R.layout.bleclient_list_item_characteristic, characteristicLayout, false);
            //特征的uuiD
            TextView characteristicUUID = view.findViewById(R.id.characteristicUUID);
            //特征属性
            TextView characteristicProperties = view.findViewById(R.id.characteristicProperties);
            //读取特征值按钮
            ImageView readCharacteristicBtn = view.findViewById(R.id.readBtn);
            //写入特征值按钮
            ImageView writeCharacteristicBtn = view.findViewById(R.id.writeBtn);
            //特征值
            TextView characteristicValue = view.findViewById(R.id.characteristicValue);
            //描述Title
            TextView descriptorTitle = view.findViewById(R.id.descriptorsTitle);
            //描述布局
            LinearLayout descriptorLayout = view.findViewById(R.id.descriptorLayout);

            //设置特征uuid
            characteristicUUID.setText(characteristic.getUuid().toString());
            //获取特征属性
            String propertiesStr = getProperties(characteristic.getProperties());
            //设置特征属性
            characteristicProperties.setText(propertiesStr);
            //根据特征属性显示特定的按钮和设置通知
            String[] propertiesArray = propertiesStr.split(",");
            for (String propertieStr : propertiesArray) {
                switch (propertieStr) {
                    case "READ": {
                        readCharacteristicBtn.setVisibility(View.VISIBLE);
                        //设置读取按钮监听
                        readCharacteristicBtn.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //读取特征值
                                bleConnectionHelper.readCharacteristic(characteristic, characteristicValue);
                            }
                        });
                        break;
                    }
                    case "WRITE NO RESPONSE":
                    case "WRITE": {
                        writeCharacteristicBtn.setVisibility(View.VISIBLE);
                        //设置写入按钮监听
                        writeCharacteristicBtn.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                showWriteDialog(characteristic);
                            }
                        });
                        break;
                    }
                    //这里只是属性设置时，设置了通知属性，检查具有该属性顺手设置通知回调，实际还是在向特征发送数值前设置
                    case "NOTIFY": {
                        //设置通知
                        bleConnectionHelper.setCharacteristicNotification(characteristic);
                    }
                }
            }

            //处理描述
            List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
            if (characteristic.getDescriptors() != null) {
                if (descriptors.size() > 0) {
                    //在描述中获取到权限值为0,无法获取该描述具体的读取权限，只能通过规定的uuid进行判断
                    descriptorTitle.setVisibility(View.VISIBLE);
                    descriptorLayout.setVisibility(View.VISIBLE);
                }
                //获取存储描述信息的布局,前面已经赋值，是否重复？
                descriptorLayout = view.findViewById(R.id.descriptorLayout);
                for (BluetoothGattDescriptor descriptor : descriptors) {
                    View descriptorView = LayoutInflater.from(mContext).inflate(
                            R.layout.bleclient_list_item_descriptor, descriptorLayout, false);
                    //描述uuid
                    TextView descriptorUUID = descriptorView.findViewById(R.id.descriptorUUID);
                    //描述读取按钮
                    ImageView readDescriptorBtn = descriptorView.findViewById(R.id.readBtn);
                    //描述写入按钮
                    ImageView writeDescriptorBtn = descriptorView.findViewById(R.id.writeBtn);
                    //设置描述值
                    TextView descriptorValue = descriptorView.findViewById(R.id.descriptorValue);

                    //设置描述uuid
                    descriptorUUID.setText(descriptor.getUuid().toString());
                    //无法判断描述的权限，只能全部显示。设置只读权限的描述，nRF也全部显示的（即显示写入和读取按钮）。
                    //设置读取按钮监听
                    readDescriptorBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            bleConnectionHelper.readDescriptor(descriptor, descriptorValue);
                        }
                    });
                    //设置写入按钮监听
                    writeDescriptorBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            showWriteDialog(descriptor);
                        }
                    });
                    descriptorLayout.addView(descriptorView);
                }
            }
            //将当前特征具体的布局添加到特征容器布局中
            characteristicLayout.addView(view);
        }


        /**
         * 特征值写入弹窗方法1,还有一个不同参数类型的弹窗方法
         */
        public void showWriteDialog(BluetoothGattCharacteristic characteristic) {
            //弹窗视图
            View view = LayoutInflater.from(itemView.getContext())
                    .inflate(R.layout.bleclient_dialog, null);
            //输入框
            EditText valueEditText = view.findViewById(R.id.valueEditText);
            //确认按钮
            TextView positiveBtn = view.findViewById(R.id.positiveBtn);

            //展示dialog
            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
            AlertDialog dialog = dialogBuilder.setView(view).show();

            //设置确认按钮监听
            positiveBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String dataStr = valueEditText.getText().toString();
                    //判断是否为十六进制字符串，原始的正则表达式是："^[A-Fa-f0-9]+\$"，去掉了\
                    if (Pattern.matches("^[A-Fa-f0-9]+$", dataStr)) {
                        //将十六进制字符串转换为字节数组发送给外设
                        bleConnectionHelper.writeCharacteristic(characteristic, hexStringToBytes(dataStr));
                        //顺便关闭弹窗
                        dialog.dismiss();
                    } else {
                        ToastUtils.showBottomToast(mContext, "$dataStr 不是十六进制");
                    }
                }
            });
        }

        /**
         * 描述值写入弹窗2，参数为
         */
        public void showWriteDialog(BluetoothGattDescriptor descriptor ){
            //弹窗视图
            View view = LayoutInflater.from(itemView.getContext()).inflate(R.layout.bleclient_dialog,null);
            //输入框
            EditText valueEditText = view.findViewById(R.id.valueEditText);
            //确认按钮
            TextView positiveBtn = view.findViewById(R.id.positiveBtn);
            //展示dialog
            AlertDialog dialog = new AlertDialog.Builder(mContext)
                    .setView(view)
                    .show();
            //设置确认按钮监听
            positiveBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String dataStr = valueEditText.getText().toString();
                    //判断是否为十六进制字符串，原始的正则表达式是："^[A-Fa-f0-9]+\$"，去掉了\
                    if (Pattern.matches("^[A-Fa-f0-9]+$", dataStr)){
                        //将十六进制字符串转换为字节数组发送给外设
                        bleConnectionHelper.writeDescriptor(descriptor,hexStringToBytes(dataStr));
                        //顺便关闭弹窗
                        dialog.dismiss();
                    }else{
                        ToastUtils.showBottomToast(mContext,dataStr +"不是十六进制");
                    }
                }
            });
        }

        /**
         * 获取具体属性
         */
        private String getProperties(int properties) {
            StringBuffer buffer = new StringBuffer();
            int i = 1;

            for (byte var4 = 8; i <= var4; ++i) {
                switch (i) {
                    case 1:
                        if ((properties & 1) != 0) {
                            buffer.append("BROADCAST,");
                        }
                        break;
                    case 2:
                        if ((properties & 2) != 0) {
                            buffer.append("READ,");
                        }
                        break;
                    case 3:
                        if ((properties & 4) != 0) {
                            buffer.append("WRITE NO RESPONSE,");
                        }
                        break;
                    case 4:
                        if ((properties & 8) != 0) {
                            buffer.append("WRITE,");
                        }
                        break;
                    case 5:
                        if ((properties & 16) != 0) {
                            buffer.append("NOTIFY,");
                        }
                        break;
                    case 6:
                        if ((properties & 32) != 0) {
                            buffer.append("INDICATE,");
                        }
                        break;
                    case 7:
                        if ((properties & 64) != 0) {
                            buffer.append("SIGNED WRITE,");
                        }
                        break;
                    case 8:
                        if ((properties & 128) != 0) {
                            buffer.append("EXTENDED PROPS,");
                        }
                }
            }

            String var10000 = buffer.toString();
            String str = var10000;
            if (str.length() > 0) {
                byte var5 = 0;
                int var6 = str.length() - 1;
                boolean var7 = false;
                if (str != null) {
                    var10000 = str.substring(var5, var6);
                    return var10000;
                }
            }
            return "";
        }
    }
}
